package snake.snakeSprites;

import boogie.game.GameState;
import boogie.game.sound.SoundManager;
import boogie.game.sprite.Sprite;
import java.awt.*;
import java.util.LinkedList;
import java.util.Random;
import snake.controll.SnakeCommand;
import snake.controll.SnakeMoveCommand;

/**
 *
 * @author Boogie
 */
public class Snake extends Sprite {

    private final class SnakeBody extends Sprite {

        //private Random rand;

        public SnakeBody(GameState gameState) {
            super(gameState, -32, -32, 32, 32);
            //rand = new Random();
        }

        @Override
        public void onUpdate() {
        }

        @Override
        public void onDraw(Graphics2D g) {
//            float red = rand.nextFloat();
//            float green = rand.nextFloat();
//            float blue = rand.nextFloat();
//            
            g.setColor(Color.WHITE);
            g.drawRect(this.getX(), this.getY(), this.getWidth() - 3, this.getHeight() - 3);

        }
    }

    private final class SnakeHead extends Sprite {

        public SnakeHead(GameState gameState) {
            super(gameState, gameState.getGame().width / 2, gameState.getGame().width / 2, 32, 32);
        }

        @Override
        public void onUpdate() {
        }

        @Override
        public void onCollide(Sprite s) {
        }

        @Override
        public void onDraw(Graphics2D g) {
            g.setColor(Color.GREEN);
            g.drawRect(this.getX(), this.getY(), this.getWidth() - 3, this.getHeight() - 3);
        }
    }
    private final SnakeHead head;
    private final LinkedList<SnakeBody> body;
    private Direction dir;
    public final LinkedList<SnakeCommand> commands;

    public Snake(GameState gameState) {
        super(gameState, gameState.getGame().width / 2,
                gameState.getGame().width / 2, 32, 32);
        body = new LinkedList<>();
        head = new SnakeHead(gameState);
        commands = new LinkedList<>();
        body.add(new SnakeBody(gameState));
        body.add(new SnakeBody(gameState));
        body.add(new SnakeBody(gameState));
        body.add(new SnakeBody(gameState));
        dir = Direction.LEFT;

    }

    @Override
    public void onCollide(Sprite s) {
        if (s instanceof SnakeBody || s instanceof BorderBlock) {
            SoundManager.getInstance().playSound("gameover");
            gameState.getGame().stop();

        }
    }

    @Override
    public void onUpdate() {
        SnakeCommand c = commands.poll();
        if (c == null) {
            c = new SnakeMoveCommand(this, dir);
        }
        c.execute();
    }

    public final void grow() {
        SoundManager.getInstance().playSound("grow");
        body.add(0, new SnakeBody(gameState));
    }

    public Direction getDirection() {
        return dir;
    }

    public void setDirection(Direction dir) {
        this.dir = dir;
    }

    public void move(Direction dir) {
        switch (dir) {
            case LEFT:
                this.goLeft();
                break;
            case RIGHT:
                this.goRight();
                break;
            case UP:
                this.goUp();
                break;
            case DOWN:
                this.goDown();
                break;
        }

    }

    //<editor-fold defaultstate="collapsed" desc="Moving Stuff">
    private void goLeft() {
        int x = this.getX();
        int y = this.getY();
        this.setPosition(x - 32, y);
        SnakeBody b = this.body.poll();
        if (b != null) {
            b.setPosition(x, y);
            this.body.add(b);
        }
    }

    private void goRight() {
        int x = this.getX();
        int y = this.getY();
        this.setPosition(x + 32, y);
        SnakeBody b = this.body.poll();
        if (b != null) {
            b.setPosition(x, y);
            this.body.add(b);
        }
    }

    private void goUp() {
        int x = this.getX();
        int y = this.getY();
        this.setPosition(x, y - 32);
        SnakeBody b = this.body.poll();
        if (b != null) {
            b.setPosition(x, y);
            this.body.add(b);
        }
    }

    private void goDown() {
        int x = this.getX();
        int y = this.getY();
        this.setPosition(x, y + 32);
        SnakeBody b = this.body.poll();
        if (b != null) {
            b.setPosition(x, y);
            this.body.add(b);
        }
    }
    //</editor-fold>

    @Override
    public void onDraw(Graphics2D g) {
    }

    //<editor-fold defaultstate="collapsed" desc="Overrides">
    @Override
    public Dimension getDimension() {
        return head.getDimension();
    }

    @Override
    public int getHeight() {
        return head.getHeight();
    }

    @Override
    public Rectangle getHitbox() {
        return head.getHitbox();
    }

    @Override
    public Point getPosition() {
        return head.getPosition();
    }

    @Override
    public int getWidth() {
        return head.getWidth();
    }

    @Override
    public int getX() {
        return head.getX();
    }

    @Override
    public int getY() {
        return head.getY();
    }

    @Override
    public void setPosition(int x, int y) {
        head.setPosition(x, y);
    }

    @Override
    public void setPosition(Point p) {
        head.setPosition(p);
    }
    //</editor-fold>
}
